package com.inwavetech.os.sync;

import android.content.Context;

import com.inwavetech.os.R;
import com.inwavetech.os.entity.Os;
import com.inwavetech.os.entity.Product;
import com.inwavetech.os.util.EnumHandler;
import com.inwavetech.os.util.SessionManager;
import com.inwavetech.os.util.SimpleResponse;
import com.inwavetech.os.util.WsseRequestConfigurator;
import com.inwavetech.os.util.request.MultipartPost;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.HashMap;

/**
 * Created by jgskin on 2/19/14.
 */
public class OsSender {

    private static final EnumHandler osStausHandler;
    private static final EnumHandler osClosingStausHandler;
    private static final EnumHandler productDiagnosysHandler;
    private static final int UPDATED = 201;

    static {
        HashMap<Integer, Enum> osStatusConfig = new HashMap<Integer, Enum>();
        osStatusConfig.put(1, Os.Status.OPEN);
        osStatusConfig.put(2, Os.Status.ACTIVE);
        osStatusConfig.put(3, Os.Status.FINISHED);

        osStausHandler = new EnumHandler(osStatusConfig);

        HashMap<Integer, Enum> osClosingStatusConfig = new HashMap<Integer, Enum>();
        osClosingStatusConfig.put(1, Os.ClosingStatus.CONCLUDED);
        osClosingStatusConfig.put(2, Os.ClosingStatus.ON_HOLD);
        osClosingStatusConfig.put(3, Os.ClosingStatus.CANCELED);

        osClosingStausHandler = new EnumHandler(osClosingStatusConfig);

        HashMap<Integer, Enum> productDiagnosysConfig = new HashMap<Integer, Enum>();
        productDiagnosysConfig.put(1, Product.Diagnosys.ADJUST);
        productDiagnosysConfig.put(2, Product.Diagnosys.BOARD_CHANGE);
        productDiagnosysConfig.put(3, Product.Diagnosys.BOARD_CHANGE_NEEDED);
        productDiagnosysConfig.put(4, Product.Diagnosys.POWER_CHANGE);
        productDiagnosysConfig.put(5, Product.Diagnosys.POWER_CHANGE_NEEDED);
        productDiagnosysConfig.put(6, Product.Diagnosys.PRODUCT_CHANGE);
        productDiagnosysConfig.put(7, Product.Diagnosys.PRODUCT_CHANGE_NEEDED);
        productDiagnosysConfig.put(8, Product.Diagnosys.TAG_NEAR);
        productDiagnosysConfig.put(9, Product.Diagnosys.FIXATION);
        productDiagnosysConfig.put(10, Product.Diagnosys.INFRA);
        productDiagnosysConfig.put(11, Product.Diagnosys.RESET);
        productDiagnosysConfig.put(12, Product.Diagnosys.COMPLEX);
        productDiagnosysConfig.put(13, Product.Diagnosys.UNINSTALL);

        productDiagnosysHandler = new EnumHandler(productDiagnosysConfig);
    }

    private final Context context;
    private final WsseRequestConfigurator wsseRequestConfigurator;

    public OsSender(Context context, SessionManager sessionManager) {
        this.context = context;
        wsseRequestConfigurator = new WsseRequestConfigurator(sessionManager);
    }

    public void send(Os os) throws OsSenderException {
        OsJson osJson;
        SimpleResponse response;

        try {
            osJson = new OsJson(os);
        } catch (JSONException e) {
            throw new OsSenderException("could not format the json message");
        }

        MultipartPost post = new MultipartPost(wsseRequestConfigurator)
                .addParam("os", osJson.toString());

        post.addFileInputStream("signature", new File(String.format("%s/%s", context.getFilesDir(), os.signature_filename)));

        try {
            response = post.execute(context.getString(R.string.api_finish_os));
        } catch (IOException e) {
            throw new OsSenderException(e.getMessage());
        }

        if (response.code != UPDATED) {
            throw new OsSenderException(String.format("bad server response - %s", response.body));
        }
    }

    public static class OsSenderException extends Exception {
        public OsSenderException(String s) {
            super(s);
        }
    }

    private class OsJson extends JSONObject {

        public OsJson(Os os) throws JSONException {
            put("id", os.original_id);
            put("service_price", os.service_price.toString());
            put("travel_price", os.travel_price.toString());
            put("roundup", os.roundup);
            put("name_responsible", os.name_responsible);
            put("service_order_closing_status_id", osClosingStausHandler.getId(os.closing_status));
            put("service_justification", os.service_justification);
            put("travel_justification", os.travel_justification);
            put("future_observation", os.future_observation);
            put("maintenance_observation", os.maintenance_observation);

            // product
            JSONObject productsJson = new JSONObject();
            for (Product product: os.products) {
                productsJson.put(product.original_id, new ProductJson(product));
            }

            put("products", productsJson);
        }
    }

    private class ProductJson extends JSONObject {
        public ProductJson(Product product) throws JSONException {
            put("service_order_diagnostic_id", productDiagnosysHandler.getId(product.diagnosys));
            put("diagnostic_detail", product.diagnosys_detail);
            put("installation_detail", product.installation_detail);
            put("installation_observation", product.installation_observation);
        }
    }
}
